package com.tootallgavin.uttt;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.*;
import android.graphics.drawable.Drawable;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;


public class utttView extends View {
    private final Bitmap mBmpPlayer1;
    private final Paint mWinPaint;
    private tttView mTttView;
    private Paint mLinePaint;
    private static final int MARGIN = 4;
    private int mSxy;
    private int mOffetX;
    private int mOffetY;
    private boolean mSelectArea;
    private int mSelectedBigCell;
    private int mSelectedSmallCell;
    private final Rect mBDstRect = new Rect();
    private final Rect mBSrcRect = new Rect();
    private final Rect mSDstRect = new Rect();
    private final Rect mSSrcRect = new Rect();
    private State[] mBigSquares = new State[9];
    private State[][] mSmallSquares = new State[9][9];
    private Paint mBmpPaint;
    private int mWinCol;
    private State mWinner;
    private int mWinRow;
    private int mWinDiag;

    public boolean checkGameFinished() {

        for (int i = 0; i < mSmallSquares.length;  i++)
            for (int j = 0; j < mSmallSquares.length;  j++){

            }

        State[] data = mBigSquares;
        boolean full = true;
        State winner = State.EMPTY;

        int col = -1;
        int row = -1;
        int diag = -1;

        // check rows
        for (int j = 0, k = 0; j < 3; j++, k += 3) {
            if (data[k] != State.EMPTY && data[k] == data[k + 1] && data[k] == data[k + 2]) {
                row = j;
                winner = data[k];
            }
            if (full && (data[k] == State.EMPTY ||
                    data[k + 1] == State.EMPTY ||
                    data[k + 2] == State.EMPTY)) {
                full = false;
            }
        }

        // check columns
        for (int i = 0; i < 3; i++) {
            if (data[i] != State.EMPTY && data[i] == data[i + 3] && data[i] == data[i + 6]) {
                col = i;
                winner = data[i];
            }
        }

        // check diagonals
        if (data[0] != State.EMPTY && data[0] == data[1 + 3] && data[0] == data[2 + 6]) {
            diag = 0;
            winner = data[0];
        } else if (data[2] != State.EMPTY && data[2] == data[1 + 3] && data[2] == data[0 + 6]) {
            diag = 1;
            winner = data[2];
        }

        if (col != -1 || row != -1 || diag != -1) {
            setFinished(winner, col, row, diag);
            return true;
        }

        // if we get here, there's no winner but the board is full.
        if (full) {
            setFinished(State.EMPTY, -1, -1, -1);
            return true;
        }
        return false;
    }
    public void setFinished(State winner, int col, int row, int diagonal) {
        mWinner = winner;
        mWinCol = col;
        mWinRow = row;
        mWinDiag = diagonal;
    }
    public void setTttViewListener() {
        mTttView.settttViewListener(new tttView.tttViewListener() {
            public void onSquareSelected(int cell) {
                setVisibility(VISIBLE);
                mTttView.setVisibility(INVISIBLE);
                setActivated(true);
                if (mSelectedBigCell > -1)
                    mSmallSquares[mSelectedBigCell][cell] = State.PLAYER1;
            }
        });
    }

    public utttView(Context context) {
        super(context);

        mTttView = null;

        mWinner = State.EMPTY;
        mWinCol = -1;
        mWinRow = -1;
        mWinDiag = -1;

        mBmpPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

        mLinePaint = new Paint();
        mLinePaint.setColor(0xFFFFFFFF);


        mLinePaint.setStyle(Paint.Style.STROKE);
        mBmpPlayer1 = getResBitmap(R.drawable.blue);
        mBSrcRect.set(0, 0, mBmpPlayer1.getWidth() - 1, mBmpPlayer1.getHeight() - 1);
        mSSrcRect.set(0, 0, mBmpPlayer1.getWidth() - 1, mBmpPlayer1.getHeight() - 1);

        mWinPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mWinPaint.setColor(0xFFFF0000);
        mWinPaint.setStrokeWidth(10);
        mWinPaint.setStyle(Paint.Style.STROKE);


        for (int i = 0; i < mSmallSquares.length;  mBigSquares[i++] = State.EMPTY)
            for (int j = 0; j < mSmallSquares.length;  mSmallSquares[i][j++] = State.EMPTY);
    }

    public boolean onTouchEvent(MotionEvent event) {

        int action = event.getAction();

        if (action == MotionEvent.ACTION_DOWN)
            return true;
        else if (action == MotionEvent.ACTION_UP) {
            int x = (int) event.getX();
            int y = (int) event.getY();

            int sxy = mSxy;
            x = (x - MARGIN) / sxy;
            y = (y - MARGIN) / sxy;
            int cell = (x + 3 * y) - 3;
            mSelectedBigCell = cell < -1 ? -1 : cell;
            this.invalidate();
            this.setActivated(false);
            this.setVisibility(INVISIBLE);
            if (mTttView != null) {
                mTttView.setVisibility(VISIBLE);
                mTttView.requestFocus();
                mTttView.setBoard(mSelectedBigCell, mSmallSquares);
            }
        }
        return true;
    }

    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        requestFocus();
        int sxy = mSxy;
        int s3 = sxy * 3 - 1;
        int x7 = mOffetX;
        int y7 = mOffetY;
        mLinePaint.setStrokeWidth(5);

        //big lines
        for (int i = 0, k = sxy; i < 2; i++, k += sxy) {
            canvas.drawLine(x7, y7 + k, x7 + s3, y7 + k, mLinePaint);
            canvas.drawLine(x7 + k, y7, x7 + k, y7 + s3, mLinePaint);
        }
        //top
        canvas.drawLine(x7, y7, x7 + s3, y7, mLinePaint);
        //bottom
        canvas.drawLine(x7, y7 + s3, x7 + s3, y7 + s3, mLinePaint);
        //left
        canvas.drawLine(x7, y7, x7, y7 + s3, mLinePaint);
        //right
        canvas.drawLine(x7 + s3, y7, x7 + s3, y7 + s3, mLinePaint);
        //small lines
        mLinePaint.setStrokeWidth(2);
        for (int i = 0, k = sxy / 3; i < 8; i++, k += (sxy / 3)) {
            canvas.drawLine(x7, y7 + k, x7 + s3, y7 + k, mLinePaint);
            canvas.drawLine(x7 + k, y7, x7 + k, y7 + s3, mLinePaint);
        }
        mLinePaint.setStyle(Paint.Style.FILL);

        /*for (int j = 0, k = 0, y = y7; j < 3; j++, y += sxy) {
            for (int i = 0, x = x7; i < 3; i++, k++, x += sxy) {
               if (mSelectedBigCell == k){
                   mBDstRect.offsetTo(MARGIN+x, MARGIN+y);
                   canvas.drawBitmap(mBmpPlayer1, mBSrcRect, mBDstRect, mBmpPaint);

               }
            }
        } */
        for (int j = 0, k = 0, y = y7; j < 3; j++, y += sxy) {

            for (int i = 0, x = x7; i < 3; i++, k++, x += sxy) {
                //big tic tac toe
                for (int j2 = 0, y2 = y, k2 = 0; j2 < 3; j2++, y2 += sxy / 3) {
                    for (int i2 = 0, x2 = x; i2 < 3; k2++, i2++, x2 += sxy / 3) {
                        //small tic tac toes
                        if (mSmallSquares[k][k2] == State.PLAYER1) {
                            mSDstRect.offsetTo(MARGIN + x2, MARGIN + y2);
                            canvas.drawBitmap(mBmpPlayer1, mSSrcRect, mSDstRect, mBmpPaint);

                        }
                    }
                }
            }
        }
        checkGameFinished();
        Log.v("uttt", String.format("%d %d %d",mWinRow,mWinCol,mWinDiag));
        if (mWinRow >= 0) {
            int y = y7 + mWinRow * sxy + sxy / 2;
            canvas.drawLine(x7 + MARGIN, y, x7 + s3 - 1 - MARGIN, y, mWinPaint);

        } else if (mWinCol >= 0) {
            int x = x7 + mWinCol * sxy + sxy / 2;
            canvas.drawLine(x, y7 + MARGIN, x, y7 + s3 - 1 - MARGIN, mWinPaint);

        } else if (mWinDiag == 0) {
            // diagonal 0 is from (0,0) to (2,2)

            canvas.drawLine(x7 + MARGIN, y7 + MARGIN,
                    x7 + s3 - 1 - MARGIN, y7 + s3 - 1 - MARGIN, mWinPaint);

        } else if (mWinDiag == 1) {
            // diagonal 1 is from (0,2) to (2,0)

            canvas.drawLine(x7 + MARGIN, y7 + s3 - 1 - MARGIN,
                    x7 + s3 - 1 - MARGIN, y7 + MARGIN, mWinPaint);
        }

    }

    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        int sx = (w - 2 * MARGIN) / 3;
        int sy = (h - 2 * MARGIN) / 3;

        int size = sx < sy ? sx : sy;

        mSxy = size;
        mOffetX = (w - 3 * size) / 2;
        mOffetY = (h - 3 * size) / 2;

        mBDstRect.set(MARGIN, MARGIN, size - MARGIN, size - MARGIN);
        mSDstRect.set(MARGIN, MARGIN, size / 3 - MARGIN, size / 3 - MARGIN);
    }

    private Bitmap getResBitmap(int bmpResId) {
        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inDither = false;

        Resources res = getResources();
        Bitmap bmp = BitmapFactory.decodeResource(res, bmpResId, opts);

        if (bmp == null && isInEditMode()) {
            // BitmapFactory.decodeResource doesn't work from the rendering
            // library in Eclipse's Graphical Layout Editor. Use this workaround instead.

            Drawable d = res.getDrawable(bmpResId);
            int w = d.getIntrinsicWidth();
            int h = d.getIntrinsicHeight();
            bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
            Canvas c = new Canvas(bmp);
            d.setBounds(0, 0, w - 1, h - 1);
            d.draw(c);
        }
        return bmp;
    }
    public void setmTttView(tttView mTttView) {
        this.mTttView = mTttView;
    }
}
